﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Display;


namespace Arcgis
{
    public partial class Form1 : Form
    {
        // 图层和状态变量
        private IGraphicsLayer _markerLayer;
        private bool _isSelecting = false;
        private List<IPoint> _selectedPoints = new List<IPoint>();
        private IGraphicsLayer _pointGraphicsLayer;
        private IPoint _destinationPoint;

        public Form1()
        {
            InitializeComponent();

            // 1. 绑定ArcGIS运行时
            if (!RuntimeManager.Bind(ProductCode.EngineOrDesktop))
            {
                MessageBox.Show("ArcGIS运行时绑定失败，请检查安装！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(1);
            }

            // 2. 初始化核心组件
            try
            {
                InitializeMarkerLayer();
                InitializeHawkEye();
                _pointGraphicsLayer = new CompositeGraphicsLayerClass();
                _destinationPoint = new PointClass();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"初始化失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void InitializeMarkerLayer()
        {
            try
            {
                _markerLayer = new CompositeGraphicsLayerClass();
                ILayer layer = _markerLayer as ILayer;
                layer.Name = "DestinationMarkers";
                axMapControl1.Map.AddLayer(layer);

                // 确保事件订阅正确
                axMapControl1.OnMouseDown -= axMapControl1_OnMouseDown;
                axMapControl1.OnMouseDown += axMapControl1_OnMouseDown;
            }
            catch (Exception ex)
            {
                throw new Exception($"标记图层初始化失败: {ex.Message}");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                _isSelecting = true;
                _selectedPoints.Clear();
                axToolbarControl1.CurrentTool = null;
                MessageBox.Show("请在地图上右键点击选择位置", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (COMException ex)
            {
                MessageBox.Show($"ArcGIS引擎错误({ex.ErrorCode}): {ex.Message}", "COM异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"操作失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            if (e.button != 2 || !_isSelecting) return;

            IPoint point = null;
            try
            {
                point = axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
                _selectedPoints.Add(point);
                AddMarkerToMap(point);
                FlashPoint(point);
                MessageBox.Show($"已选择点: X={point.X:F2}, Y={point.Y:F2}", "坐标", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"选点失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if (point != null) Marshal.ReleaseComObject(point);
            }
        }

        private void AddMarkerToMap(IPoint point)
        {
            ISimpleMarkerSymbol markerSymbol = null;
            IElement element = null;
            try
            {
                markerSymbol = new SimpleMarkerSymbolClass()
                {
                    Style = esriSimpleMarkerStyle.esriSMSCircle,
                    Color = GetRGBColor(255, 0, 0),
                    Size = 10
                };

                element = new MarkerElementClass()
                {
                    Geometry = point
                };
                ((IMarkerElement)element).Symbol = markerSymbol;

                ((IGraphicsContainer)_markerLayer).AddElement(element, 0);
                axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
            }
            finally
            {
                if (markerSymbol != null) Marshal.ReleaseComObject(markerSymbol);
                if (element != null) Marshal.ReleaseComObject(element);
            }
        }

        private void FlashPoint(IPoint point)
        {
            try
            {
                // 仅添加标记，不闪烁
                AddMarkerToMap(point);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"添加标记失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
        private void InitializeHawkEye()
        {
            try
            {
                if (axMapControl1 == null || axMapControl2 == null)
                    throw new Exception("地图控件未初始化");

                axMapControl2.Map.ClearLayers();
                axMapControl1.OnExtentUpdated += axMapControl1_OnExtentUpdated;
                axMapControl1.OnMapReplaced += axMapControl1_OnMapReplaced;
                axMapControl2.OnMouseMove += axMapControl2_OnMouseMove;

                UpdateHawkEyeView();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"鹰眼初始化失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void UpdateHawkEyeView()
        {
            try
            {
                axMapControl2.Map.ClearLayers();
                ILayer overviewLayer = GetOverviewLayer(axMapControl1.Map);
                if (overviewLayer != null)
                {
                    axMapControl2.AddLayer(overviewLayer);
                    axMapControl2.Extent = axMapControl1.FullExtent;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("更新鹰眼视图时出错: " + ex.Message);
            }
        }

        private ILayer GetOverviewLayer(IMap map)
        {
            try
            {
                int layerCount = map.LayerCount;
                if (layerCount == 0)
                {
                    MessageBox.Show("地图中没有图层！");
                    return null;
                }

                ILayer overviewLayer = map.get_Layer(0);
                for (int i = 1; i < layerCount; i++)
                {
                    ILayer candidateLayer = map.get_Layer(i);
                    if (candidateLayer.AreaOfInterest != null &&
                        candidateLayer.AreaOfInterest.Width > overviewLayer.AreaOfInterest.Width)
                    {
                        overviewLayer = candidateLayer;
                    }
                }
                return overviewLayer;
            }
            catch (Exception ex)
            {
                MessageBox.Show("获取鹰眼图层时出错: " + ex.Message);
                return null;
            }
        }

        private IColor GetRGBColor(int r, int g, int b)
        {
            IRgbColor color = new RgbColorClass() { Red = r, Green = g, Blue = b };
            return color;
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
            try
            {
                if (_markerLayer != null) Marshal.ReleaseComObject(_markerLayer);
                if (_pointGraphicsLayer != null) Marshal.ReleaseComObject(_pointGraphicsLayer);
                if (_destinationPoint != null) Marshal.ReleaseComObject(_destinationPoint);
                axMapControl1.Dispose();
                axMapControl2.Dispose();
            }
            catch { /* 确保窗体能关闭 */ }
        }

        private void axMapControl1_OnExtentUpdated(object sender, IMapControlEvents2_OnExtentUpdatedEvent e)
        {
            IEnvelope pEnv = (IEnvelope)e.newEnvelope;
            IRectangleElement pRectangleEle = new RectangleElement() as IRectangleElement;
            IElement pEle = pRectangleEle as IElement;
            pEle.Geometry = pEnv;

            IRgbColor pColor = new RgbColor() as IRgbColor;
            pColor.Red = 255;
            pColor.Green = 0;
            pColor.Blue = 0;
            pColor.Transparency = 255;

            ILineSymbol pOutline = new SimpleLineSymbol() as ILineSymbol;
            pOutline.Width = 2;
            pOutline.Color = pColor;

            pColor.Red = 255;
            pColor.Green = 0;
            pColor.Blue = 0;
            pColor.Transparency = 0;

            IFillSymbol pFillSymbol = new SimpleFillSymbol() as IFillSymbol;
            pFillSymbol.Color = pColor;
            pFillSymbol.Outline = pOutline;
            IFillShapeElement pFillShapeEle = pEle as IFillShapeElement;
            pFillShapeEle.Symbol = pFillSymbol;

            IGraphicsContainer pGra = axMapControl2.Map as IGraphicsContainer;
            IActiveView pAv = pGra as IActiveView;
            pGra.DeleteAllElements();
            pGra.AddElement((IElement)pFillShapeEle, 0);
            pAv.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            InitializeHawkEye();
        }

        private void axMapControl2_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            try
            {
                if (e.button != 1) return;

                IPoint pPoint = new ESRI.ArcGIS.Geometry.Point() as IPoint;
                pPoint.PutCoords(e.mapX, e.mapY);
                axMapControl1.CenterAt(pPoint);
                axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
            }
            catch (Exception ex)
            {
                MessageBox.Show("鹰眼地图鼠标移动处理出错: " + ex.Message);
            }
        }

        private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
        {
            UpdateHawkEyeView();
        }

        private void axToolbarControl1_OnMouseDown(object sender, IToolbarControlEvents_OnMouseDownEvent e)
        {
            // 工具栏鼠标事件处理
        }
    }
}